//////////////////////////////////////////////////////////////////////////////////
//	File	:	Game.h
//	Author	:	Yuri Oyoko
//	Purpose	:	Controls the main game loop and switches states
//////////////////////////////////////////////////////////////////////////////////

//Includes
#include <windows.h>
#include "Game.h"
#include "Definitions.h"
#include "BaseState.h"
//#include "CAnimation_Manager.h"

Game::Game()
{
	CurrentGameState = NULL;
	Direct3DInstance = NULL;
	DirectInputInstance = NULL;
	DirectSoundInstance = NULL;
	TextureManagerInstance = NULL;
	WaveManagerInstance = NULL;

	dwFrames = 0;
	dwCurrentTime = 0;
	dwLastUpdateTime = 0;
	dwElapsedTime = 0;
	szFPS[0] = '\0';
}
Game::~Game()
{
}

Game* Game::GetInstance()
{
	static Game theGame;
	return &theGame;
}
void Game::Initialize(HWND hWnd, HINSTANCE hInstance, bool WindowedMode)
{
	//Poit to SGD Wrapper instances
	Direct3DInstance = CSGD_Direct3D::GetInstance();
	DirectInputInstance = CSGD_DirectInput::GetInstance();
	DirectSoundInstance = CSGD_DirectSound::GetInstance();
	TextureManagerInstance = CSGD_TextureManager::GetInstance();
	WaveManagerInstance = CSGD_WaveManager::GetInstance();

	//Initialize SGD Wrapper instances
	Direct3DInstance->InitDirect3D(hWnd, ScreenWidth, ScreenHeight, WindowedMode, VSyncOn);
	IsWindowed = WindowedMode;
	
	DirectInputInstance->InitDirectInput(hWnd, hInstance, DI_KEYBOARD | DI_MOUSE);
	DirectSoundInstance->InitDirectSound(hWnd);
	TextureManagerInstance->InitTextureManager(Direct3DInstance->GetDirect3DDevice(), Direct3DInstance->GetSprite());
	WaveManagerInstance->InitWaveManager(hWnd, DirectSoundInstance->GetDSObject());

	theElapsedTime = 0;
	ChangeState(MainMenuState::GetInstance());
	



}

void Game::Shutdown()
{
	if(WaveManagerInstance)
	{
		WaveManagerInstance->ShutdownWaveManager();
		WaveManagerInstance = NULL;
	}
	if(TextureManagerInstance)
	{
		TextureManagerInstance->ShutdownTextureManager();
		TextureManagerInstance = NULL;
	}
	if(DirectSoundInstance)
	{
		DirectSoundInstance->ShutdownDirectSound();
		DirectSoundInstance = NULL;
	}
	if(DirectInputInstance)
	{
		DirectInputInstance->ShutdownDirectInput();
		DirectInputInstance = NULL;
	}
	if(Direct3DInstance)
	{
		Direct3DInstance->ShutdownDirect3D();
		Direct3DInstance = NULL;
	}
}
bool Game::Main()
{
	dwFrames++;
	dwCurrentTime = GetTickCount(); 
	// Even better to use timeGetTime()
	dwElapsedTime = dwCurrentTime - dwLastUpdateTime;
	if(dwElapsedTime >= 1000)
	{        
		wsprintf(szFPS, "FPS: %u", (UINT)(dwFrames * 1000.0 / dwElapsedTime));       
		dwFrames = 0;        
		dwLastUpdateTime = dwCurrentTime;
	}

	DWORD StartTime = GetTickCount();
	static DWORD LastTime = GetTickCount();
	theElapsedTime = (float)(StartTime - LastTime)/1000.0f;
	LastTime = StartTime;

	static float Ticker = 0.0f;
	Ticker += theElapsedTime;
	if(Ticker > 1.0f)
	{
		Ticker = 0.0f;
	}

	//Gets input for the game
	GetInput();
	
		//Gets input for the state
		CurrentGameState->GetInput();
		if(CurrentGameState)
			//Calls the state's update function if the state is valid
			CurrentGameState->Update(theElapsedTime);
		else
			//Exits the game is there is no state
			return false;
		
		//Calls the state's render function
		CurrentGameState->Render();
	

	return true;
}
void Game::ChangeState(BaseState *newState)
{
	if(CurrentGameState)
		CurrentGameState->Exit();
	CurrentGameState = newState;
	
	if(CurrentGameState)
		CurrentGameState->Enter();
}

void Game::GetInput()
{
	DirectInputInstance->ReadDevices();
	if (DirectInputInstance->KeyPressed(DIK_RETURN) && (DirectInputInstance->KeyDown(DIK_LMENU) || DirectInputInstance->KeyDown(DIK_RMENU)))
	{
		IsWindowed = !IsWindowed;
		Direct3DInstance->ChangeDisplayParam(ScreenWidth, ScreenHeight, IsWindowed);
		CSGD_DirectInput::GetInstance()->ReadDevices();
	}
}